<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:fo="http://www.w3.org/1999/XSL/Format"
	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
			 xmlns:s="http://www.w3.org/2001/XMLSchema"
			 xmlns:s0="http://tempuri.org/" 
			 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
			 xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
			 xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/">
	<xsl:variable name="service.name" select="//*[local-name()='service']/@name"/>
	<xsl:variable name="service.endpoint" select="//*[local-name()='service']/*[local-name()='port']/*[local-name()='address']/@location"/>
	<xsl:variable name="service.namespace" select="//*[local-name()='schema']/@targetNamespace"/>

	<xsl:output method="text"/>
	
<xsl:template match="/"> 	
public class <xsl:value-of select="$service.name"/>
{	
    private string ENDPOINT = "<xsl:value-of select="$service.endpoint"/>";
    private string NAMESPACE = "<xsl:value-of select="$service.namespace"/>";

    public <xsl:value-of select="$service.name"/>()
    {
        //
        // TODO: Add any constructor code required
        //
    }
<xsl:apply-templates select="//*[local-name()='portType']"/>

    private string envelope (string data)
    {
        string output="";
        output+="&lt;soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"&gt;";                            
        output+="&lt;soap:Body&gt;" + data;  
        output+="&lt;/soap:Body&gt;";  
        output+="&lt;/soap:Envelope&gt;";  
        return output;
    }
    
    private string openf(string address, string data)
    {
        System.Net.WebRequest myRequest = System.Net.WebRequest.Create(address); 
        myRequest.Method = "POST";
        myRequest.ContentType = "application/x-www-form-urlencoded";	
		
        byte[] bytes = System.Text.Encoding.ASCII.GetBytes (data);
        myRequest.ContentLength = bytes.Length;
        System.IO.Stream outputStream = myRequest.GetRequestStream (); 
        outputStream.Write (bytes, 0, bytes.Length);		
		outputStream.Close();
		
        System.Net.WebResponse myResponse = myRequest.GetResponse();
        System.IO.StreamReader myStream = new System.IO.StreamReader(myResponse.GetResponseStream());
        string result = myStream.ReadToEnd();	
        myStream.Close();
        myResponse.Close();
        return result;	
    }
	
    private object invoke(string data, string nodename, bool array) // invoke                                                                                                                                                                                                                                                                               
    {
        System.Xml.XmlDocument mdom = new System.Xml.XmlDocument();
        string response = openf(ENDPOINT, envelope(data));
        string[] result;
        System.Collections.ArrayList tmp = new System.Collections.ArrayList();
        System.Diagnostics.Debug.Write(response);
        mdom.LoadXml(response);
        foreach (System.Xml.XmlElement node in mdom.SelectNodes("//*[local-name()='" + nodename + "']"))
        {
            tmp.Add(node.InnerText);
        }
        result = (string[])tmp.ToArray(typeof(string));
        if (array)
        {
            return result;
        }
        else
        {
            return result[0];
        }
        //return array ? result : result[0];
    } // invoke   
}
	
</xsl:template>


	<xsl:template match="//*[local-name()='element']">
	<xsl:for-each select="./*[local-name()='complexType']/*[local-name()='sequence']/*[local-name()='element']">
		<xsl:value-of select="concat(substring-after(@type,':'),' ',@name)"/><xsl:if test="following-sibling::*[local-name()='element']">, </xsl:if>
	</xsl:for-each>
</xsl:template>


	<xsl:template match="//*[local-name()='operation']">
		<xsl:variable name="name" select="@name"/>
		<xsl:variable name="response" select="//*[local-name()='element'][@name=concat($name,'Response')]"/>
		<xsl:variable name="type" select="$response/*[local-name()='complexType']/*[local-name()='sequence']/*[local-name()='element']"/>
		<xsl:variable name="type.name">
			<xsl:choose>
				<xsl:when test="contains($type/@type,':')">
					<xsl:value-of  select="substring-after($type/@type,':')"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="$type/@type"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<xsl:variable name="type.max">
			<xsl:choose>
				<xsl:when test="$type/@maxOccurs='unbounded'">true</xsl:when>
				<xsl:otherwise>false</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
		<xsl:variable name="type.suffix">
			<xsl:choose>
				<xsl:when test="$type/@maxOccurs='unbounded'">[]</xsl:when> 
			</xsl:choose>
		</xsl:variable>
<xsl:if test="not (preceding::*[local-name()='operation'][@name=$name])">
    public <xsl:value-of select="concat($type.name,$type.suffix,' ',@name)"/> (<xsl:apply-templates select="//*[local-name()='element'][@name=$name]"/>)
    {
        bool is_array=<xsl:value-of select="$type.max"/>;
        string request="&lt;<xsl:value-of select="@name"/> xmlns=\"" + NAMESPACE + "\"&gt;";<xsl:call-template name="form.invoke">
	<xsl:with-param name="method" select="@name"/>
</xsl:call-template>
        request+="&lt;/<xsl:value-of select="@name"/>&gt;";
        return (<xsl:value-of select="concat($type.name,$type.suffix)"/>) invoke (request, "<xsl:value-of select="@name"/>Result", is_array);
    }

</xsl:if>
		
	</xsl:template>

	
<xsl:template name="form.invoke">
	<xsl:param name="method"/>
	<xsl:param name="for" select="//*[local-name()='element'][@name=$method]/*[local-name()='complexType']/*[local-name()='sequence']/*[local-name()='element']"/>
	<xsl:param name="me" select="$for[1]"/>
	<xsl:param name="next" select="$for[position()!=1]"/><xsl:if test="$me"> 
        request+="&lt;<xsl:value-of select="$me/@name"/>&gt;" + <xsl:value-of select="$me/@name"/> + "&lt;/<xsl:value-of select="$me/@name"/>&gt;";<xsl:if test="$next">
<xsl:call-template name="form.invoke">
<xsl:with-param name="for" select="$next"/>
</xsl:call-template>
	</xsl:if></xsl:if>
</xsl:template>

	<xsl:template match="//*[local-name()='portType']">

		<xsl:apply-templates select="./*[local-name()='operation']">
		</xsl:apply-templates>
	</xsl:template>


</xsl:stylesheet> 
